﻿@page "/System/SysMenu"

@namespace SageKing.Studio.Pages.MenuPage


@implements IMenuTab<SysMenu, long>
@implements IReuseTabsPage

@using Microsoft.FluentUI.AspNetCore.Components
@using SageKing.Studio.Pages.SysMenuPage.component

@using ButtonType=AntDesign.ButtonType
@using IMessageService=AntDesign.IMessageService

<PageTitle>@TabTitle</PageTitle>

@inject AntDesign.IMessageService _message
@inject IConfirmService _confirmService

@inject SysMenuService dataService

@if (data == null)
{
    <Spin size="SpinSize.Large" Tip="Loading..." />
}
else
{
    <FluentSplitter Orientation="@orientation" OnResized=OnResizedHandler Class="height_splitter" BarSize="6" Panel1Size="20%" Panel1MinSize="10%" Panel2MinSize="30%" Panel2Size="80%">
        <Panel1>
            <Search @bind-Value="@searchKey" Placeholder="Search.." BindOnInput />
            <Tree TItem="SysMenu"
                  DataSource="data" @ref="_tree" Draggable BlockNode ShowIcon ShowLeafIcon="false" ShowLine="true" DefaultExpandParent="true"
                  SwitcherIcon="down" DefaultExpandedKeys="@defaultExpandedKeys" @bind-SelectedKey="treeSelectedKey"
                  TitleExpression="x => x.DataItem.Title"
                  ChildrenExpression="x => x.DataItem.Children"
                  IconExpression="x => x.DataItem.Icon"
                  IsLeafExpression="x => x.DataItem.Children?.Count==0"
                  KeyExpression="x => x.DataItem.Id.ToString()"
                  OnNodeLoadDelayAsync="OnNodeLoadDelayAsync"
                  SearchValue="@searchKey" MatchedClass="site-tree-search-value" HideUnmatched
                  OnDrop="onDrop" OnDragEnd="OnDragEnd" OnClick="OnClick" OnDblClick="OnDBClick">
                <SwitcherIconTemplate>
                    <Icon Type="down" />
                </SwitcherIconTemplate>
                <TitleTemplate>
                    <Dropdown Trigger="new Trigger[] { Trigger.ContextMenu }">
                        <Overlay>
                            <Menu>
                                <MenuItem OnClick="()=>AddData(context)">新增</MenuItem>
                                <MenuItem OnClick="()=>EditData(context)">修改</MenuItem>
                                <MenuItem OnClick="()=>CopyData(context)">复制</MenuItem>
                                <MenuItem OnClick="()=>DeleteData(context)">删除</MenuItem>
                            </Menu>
                        </Overlay>
                        <ChildContent>
                            <div class="menu-title">
                                @context.DataItem.Title
                            </div>
                        </ChildContent>
                    </Dropdown>
                </TitleTemplate>
            </Tree>
        </Panel1>
        <Panel2>
            <Card Title="@modelTitle">
                <ChildContent>
                    <SysMenuEdit @ref=@edit Title="@modelTitle" model="@addModel"></SysMenuEdit>
                </ChildContent>
                <ActionTemplate>
                    <CardAction>
                        <Button Type="@ButtonType.Primary" Icon="@IconType.Outline.Save" OnClick=@((e)=> HandleOk(e))>@modelOkTitle</Button>
                        @if (addModel.Id > 0)
                        {
                            <Button Type="@ButtonType.Default" Danger Icon="@IconType.Outline.Delete" OnClick=@((e)=> DeleteData(addModel))>删除</Button>
                        }
                    </CardAction>
                </ActionTemplate>
            </Card>

        </Panel2>
    </FluentSplitter>

}

<style>
    .site-tree-search-value {
        color: #f50;
    }

    .ant-card-actions > li {
        margin: 5px;
        text-align: right;
    }

    .menu-title {
        text-align: center;
        min-width: 35px;
        height: auto;
        line-height: 25px;
    }

    .height_splitter {
        min-height: @(height_splitter + "px");
    }
</style>

@code {
    Orientation orientation = Orientation.Horizontal;
    private void OnResizedHandler(SplitterResizedEventArgs args)
    {
        Console.WriteLine($"Size changed: {args.Panel1Size}, {args.Panel2Size}");
    }
}

@code {

    //model base btn title
    string modelTitle = "新增";
    string modelOkTitle = "保存";
    string modelCancelText = "取消";

    //add
    bool _visible = false;
    bool addloading = false;
    SysMenu addModel;
    SysMenuEdit edit;

    //add
    RenderFragment FormParentTemplate()
    {
        return@<SysMenuEdit @ref=@edit Title="@modelTitle" model="@addModel"></SysMenuEdit>;
    }

    async Task HandleOk(MouseEventArgs e)
    {
        try
        {

            addloading = true;
            if (edit != null)
            {
                var result = await edit.Me.Save();
                if (!result)
                {
                    _visible = true;
                    addloading = false;
                    return;
                }
                dataService.CacheRefresh(0);
            }
            await Refresh(false);
            _ = _message.SuccessAsync($"{modelTitle}【{addModel.Title}】成功！");
            _visible = false;
            addloading = false;
            EditData(addModel);
            treeSelectedKey = addModel.Id.ToString();
            // addEdit?.Reset();
        }
        catch (Exception ex)
        {
            Error?.ProcessError(ex, $"{modelTitle}【{addModel.Title}】失败！");
        }
    }

    #region crud

    async void AddData(TreeNode<SysMenu> treeNode)
    {
        var row = treeNode.DataItem;
        treeTitle = getNodeTitleAll(treeNode);
        var allParentId = getNodeIdAll(treeNode);
        defaultExpandedKeys = allParentId.Split(',');
        addModel = new SysMenu();
        addModel.Pid = row.Id;
        modelTitle = $"#{treeTitle}-:>新增";
        modelOkTitle = "保存";
        // _visible = true;
        // addloading = false;
        await Task.CompletedTask;

    }

    async void CopyData(TreeNode<SysMenu> treeNode)
    {
        var row = treeNode.DataItem;
        treeTitle = getNodeTitleAll(treeNode);
        var allParentId = getNodeIdAll(treeNode);
        defaultExpandedKeys = allParentId.Split(',');
        addModel = row.Clone<SysMenu>();
        addModel.Id = 0;
        addModel.Pid = row.Pid;
        modelTitle = $"#{treeTitle}-:>复制";
        modelOkTitle = "保存";
        // _visible = true;
        // addloading = false;
        await Task.CompletedTask;

    }

    async Task EditData(TreeNode<SysMenu> treeNode)
    {
        var row = treeNode.DataItem;
        treeTitle = getNodeTitleAll(treeNode);

        var allParentId = getNodeIdAll(treeNode);
        defaultExpandedKeys = allParentId.Split(',');

        EditData(row);
        // _visible = true;
        // addloading = false;
        await Task.CompletedTask;
    }

    async void DeleteData(TreeNode<SysMenu> treeNode)
    {
        var row = treeNode.DataItem;
        await DeleteData(row);
    }

    void EditData(SysMenu row)
    {
        addModel = row.Clone<SysMenu>();
        modelTitle = $"#{treeTitle}-:>编辑";
        modelOkTitle = "保存";
        edit?.OnSearchIcon(addModel.Icon);
        // _visible = true;
        // addloading = false;
    }
    async Task DeleteData(SysMenu row)
    {
        if (row.Id <= 0)
        {
            return;
        }
        string content = $"确认删除【{row.Title}】";
        var confirmResult = await _confirmService.Show(content + "?", "提示", ConfirmButtons.OKCancel);
        if (confirmResult == ConfirmResult.OK)
        {

            await dataService.Delete(row.Id);
            dataService.CacheRefresh(0);
            await Refresh(false);
            _ = _message.SuccessAsync($"删除【{row.Name}】成功", 2);
            addModel = new SysMenu();
            modelTitle = "新增";
            StateHasChanged();
        }
    }
    #endregion

}

@code {

    bool loading;
    static bool IsfirstRender = false;

    double height_splitter = BrowserConsts.browserHeight;
    double height_splitter_offset = 133;

    //tree
    Tree<SysMenu> _tree;
    string treeSelectedKey;
    string[] defaultExpandedKeys = Array.Empty<string>();
    string treeTitle = string.Empty;
    string searchKey;

    IEnumerable<SysMenu> data;
    IEnumerable<SysMenu> selectedRows;

    //local cache
    Dictionary<long, string> treeTitleCache;

    //search
    SysMenu searchModel;

    PaginationEventArgs pageargs = new PaginationEventArgs(1, 10);
    PageBase<SysMenu> pageData;

    #region init
    #region menu
    public IMenuTab<SysMenu, long> MeTab { get { return this; } }

    public IBaseServiceCache<SysMenu, long> MenuService
    { get { return dataService; } }

    [SupplyParameterFromQuery(Name = "menuid")]
    public long menuid { get; set; }

    [Parameter]
    public string TabTitle { get; set; } = "菜单配置";

    [Parameter]
    public string TabIcon { get; set; } = "home";

    public RenderFragment GetPageTitle() =>
    @<div>
        <Icon Type="@TabIcon" /> @TabTitle
    </div>
    ;
    #endregion

    [CascadingParameter]
    public Error? Error { get; set; }

    protected override async Task OnInitializedAsync()
    {
        try
        {
            await InitSelectData();
            await Refresh(false);
            await MeTab.InitTabTitle();
        }
        catch (Exception ex)
        {
            Error?.ProcessError(ex, TabTitle);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            if (height_splitter != BrowserConsts.WindowSize.pageHeight)
            {
                height_splitter = BrowserConsts.WindowSize.pageHeight - height_splitter_offset;
                StateHasChanged();
            }

        }
        await Task.CompletedTask;
    }

    async Task InitSelectData()
    {
        addModel = new SysMenu();
        selectedRows = new List<SysMenu>();
        searchModel = new SysMenu();

        treeTitleCache = new Dictionary<long, string>();

        await Task.CompletedTask;
    }

    #endregion

    #region tree
    private void ExpandAll()
    {
        _tree.ExpandAll();
    }

    private void ExpandAllChild()
    {
        _tree.ExpandAll();
    }



    public async Task OnNodeLoadDelayAsync(TreeEventArgs<SysMenu> args)
    {
        var dataItem = ((SysMenu)args.Node.DataItem);
        // dataItem.Children.Clear();
        //load children
        await Task.CompletedTask;
    }

    async Task OnClick(TreeEventArgs<SysMenu> e)
    {
        await EditData(e.Node);
    }

    void OnDBClick(TreeEventArgs<SysMenu> e)
    {
        e.Node.Expand(!e.Node.Expanded);
    }

    async void onDrop(TreeEventArgs<SysMenu> e)
    {
        if (e.TargetNode.DataItem.Id != e.Node.DataItem.Pid)
        {
            var allNodeParentId = getNodeIdAll(e.Node);
            var allTargetParentId = getNodeIdAll(e.TargetNode);

            e.Node.DataItem.Pid = e.TargetNode.DataItem.Id;
            await dataService.Update(e.Node.DataItem);
            dataService.CacheRefresh(0);
            treeTitleCache.Remove(e.Node.DataItem.Id);
            addModel = e.Node.DataItem.Clone<SysMenu>();
            await Refresh(false);
            treeSelectedKey = e.Node.DataItem.Id.ToString();
            defaultExpandedKeys = allNodeParentId.Split(',').Concat(allTargetParentId.Split(',')).ToArray();
        }
    }

    void OnDragEnd(TreeEventArgs<SysMenu> e)
    {

    }

    string getNodeTitleAll(TreeNode<SysMenu> treeNode)
    {
        var currTitle = treeNode.DataItem.Title;
        var getParentNodes = treeNode.GetPreviousNode();
        if (getParentNodes == null)
        {
            return currTitle;
        }
        currTitle = getNodeTitleAll(getParentNodes) + "->" + currTitle;

        return currTitle;

    }
    string getNodeIdAll(TreeNode<SysMenu> treeNode)
    {
        var id = treeNode.DataItem.Id.ToString();
        var getParentNodes = treeNode.GetPreviousNode();
        if (getParentNodes == null)
        {
            return id;
        }
        id = getNodeIdAll(getParentNodes) + "," + id;

        return id;

    }
    #endregion

    async Task Refresh(bool notice = true)
    {
        data = await dataService.GetToTreeCacheAsync();
    }

    void ReSet()
    {
        searchModel = new SysMenu();
    }

    void Message(string msg = "查询成功")
    {
        _ = _message.SuccessAsync(msg);
    }
}
